home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 173_01 / cstock.lxi < prev    next >
Text File  |  1980-01-01  |  6KB  |  217 lines

  1. /*
  2.  * Lexical Analyzer for C Library Driver
  3.  *    - evaluates C chars, strings, ints, and floats
  4.  *    - accepts unquoted chars and strings of printing characters
  5.  */
  6.  
  7. ascii    = [\0-\177];          /* Any ASCII character */
  8. white    = [\n\r\t ];          /* The white spaces */
  9. sign     = [-+];               /* Numeric signs */
  10. digit    = [0-9];              /* The digits */
  11. hexdigit = [0-9A-Fa-f];        /* The hexadecimal digits */
  12. hexflag  = [Xx];               /* Inidcator of a hexadecimal constant */
  13. expflag  = [Ee];               /* Inidcator of a floating exponent */
  14.  
  15. t_atom = [!-~];                  /* All the printing characters */
  16. text   = [!#-&(-/:-~](t_atom)*;  /* Text can't start with a digit, " or ' */
  17.  
  18. e_particle   = "\\" ascii;    /* An escaped ascii character */
  19. s_particle   = [^\\"];        /* Anything besides an escape or a quote */
  20. c_particle   = [^\\'];        /* Anything besides an escape or an apostrophe */
  21.  
  22. c_atom = e_particle | c_particle; /* Anything but end of char */
  23. s_atom = e_particle | s_particle; /* Anything but end of string */
  24.  
  25. string = '"' s_atom*  '"';
  26. char   = "'" c_atom*  "'";
  27.  
  28. %{
  29. #include "std.h"
  30. #include "clib.h"
  31.  
  32. TEXT yytext[100];
  33. INTEGER yyival;
  34. FLOAT yyfval, pow();
  35. %}
  36. %%
  37.  
  38. ARG               {return(ARG);}
  39. PRINTF           {return(PTF);}
  40. ISLOWER        {return(ILO);}
  41. EXIT           {return(EXT);}
  42.  
  43. [-]*(digit)(hexflag)*(hexdigit)* { 
  44.        {register TEXT *p = yytext; 
  45.         BOOLEAN minus = FALSE;
  46.         INTEGER base;
  47.  
  48.         gettoken(yytext, sizeof(yytext));
  49.         yyival = 0;
  50.         if(*p == '-') {
  51.             ++p;
  52.             minus = TRUE;
  53.         }
  54.         base = 10;
  55.         if(*p == '0') {
  56.             ++p;
  57.             if(*p == 'X' || *p == 'x') {
  58.                 ++p;
  59.                 base = 16;
  60.             } else
  61.                 base =  8;
  62.         }
  63.         do {
  64.             yyival = base*yyival + hex(*p);
  65.         } while(*++p);
  66.         if(minus) yyival = -yyival;
  67.         printf("\nLEX/ICON: %s is %d (decimal)\n", yytext, yyival);
  68.         return(ICON);
  69.         }}
  70.  
  71. [-]*(digit)*"."*(digit)*expflag*sign*digit* {{
  72.         register TEXT *p = yytext; 
  73.         FLOAT divisor = 10.0, multiplier = 0.0;
  74.         BOOLEAN minus = FALSE, expminus = FALSE;
  75.         BOOLEAN decimal = FALSE, exponent = FALSE;
  76.  
  77.         gettoken(yytext, sizeof(yytext));
  78.         yyfval = 0.0;
  79.         if(*p == '-') {
  80.             ++p;
  81.             minus = TRUE;
  82.         }
  83.  
  84.         do {
  85.             switch(*p) {
  86.             case '.': decimal = TRUE; 
  87.                       break;
  88.  
  89.             case 'e':
  90.             case 'E': exponent = TRUE;
  91.                       if(*(p+1) == '-' || *(p+1) == '+')
  92.                             expminus = (*++p == '-') ? TRUE : FALSE;
  93.                       break;
  94.  
  95.             default : if(!decimal && ! exponent) {
  96.                           yyfval = 10. * (yyfval) + (*p - '0');
  97.                           break;
  98.                        } else if(!exponent) {
  99.                           yyfval = yyfval + (*p - '0')/divisor;
  100.                           divisor *= 10.;
  101.                           break;
  102.                        } else
  103.                           multiplier = 10. * multiplier + (*p - '0');
  104.             }
  105.         } while (*++p);
  106.  
  107.             if(minus) yyfval = -yyfval;
  108.             if(expminus) multiplier = -multiplier;
  109.             if(exponent) yyfval = yyfval * pow(10., multiplier);
  110.             printf("\nLEX/FCON: %s is %f\n", yytext, yyfval);
  111.             return(FCON);
  112.         }}
  113.  
  114. text  {
  115.        gettoken(yytext, sizeof(yytext));
  116.        if(strlen(yytext) == 1) {
  117.            printf("\nLEX/CCON: '%s'\n", yytext);
  118.            return(CCON);
  119.        } else {
  120.           printf("\nLEX/SCON: \"%s\"\n", yytext);
  121.           return(SCON);
  122.        }    
  123.       }
  124.  
  125. string  {
  126.           gettoken(yytext, sizeof(yytext));
  127.           strcpy(yytext, yytext+1);
  128.           yytext[strlen(yytext)-1] = NULL;
  129.           descape(yytext);
  130.           printf("\nLEX/SCON: \"%s\"\n", yytext);
  131.           return(SCON);
  132.         }
  133.  
  134. char  {
  135.        gettoken(yytext, sizeof(yytext));
  136.        strcpy(yytext, yytext+1);
  137.        yytext[strlen(yytext)-1] = NULL;
  138.        descape(yytext);
  139.        printf("\nLEX/CCON: '%s'\n", yytext);
  140.        return(CCON);
  141.       }
  142.  
  143. white(white)*    {return(LEXSKIP);}
  144.  
  145. %%
  146.  
  147. lexgetc(){
  148.     static BOOLEAN newline = TRUE;
  149.     register int c;
  150.  
  151.     if(newline)
  152.         printf("%s>", "C Lib");
  153.  
  154.     if((c = getc(lexin)) == '\n')
  155.         newline = TRUE;
  156.     else
  157.         newline = FALSE;    
  158.  
  159.     return(c);
  160. }
  161.  
  162. /*
  163. ** Translate escape sequences in a character string
  164. */
  165. descape(str)
  166. register STRING str;
  167. {
  168.         register STRING s;
  169.         COUNT i;
  170.  
  171.         for(s = str; *str; s++, str++) {
  172.  
  173.             if(*str != '\\')
  174.                 *s = *str;
  175.             else if (0 <= (i = ndex("'\"bnrtf", *++str)))
  176.                 *s = "'\"\b\n\r\t\f"[i];
  177.             else if (isdigit(*str)) { register BYTE d;
  178.                 *s = *str - '0';
  179.                 for (i=0; (d = *(str+1)) && isdigit(d) && i < 3; i++, str++)
  180.                         *s = (*s << 3) + d - '0';
  181.             }
  182.         }
  183.         *s = '\0';
  184. }
  185.  
  186. /*
  187. ** Find the index of a character in a string
  188. */
  189. INTEGER ndex(str, chr)
  190. register STRING str;
  191. CHARACTER chr;
  192. {
  193.     register COUNT i;
  194.  
  195.     for(i = 0; *str; i++, str++)
  196.         if(*str == chr)    return(i);
  197.     return(-1);
  198. }
  199.  
  200. /*
  201. ** Convert a hex digit (ASCII)
  202. */
  203. INTEGER hex(c)
  204. register CHARACTER c;
  205. {
  206.         if (isdigit(c))
  207.                 return (c - '0');
  208.         else if ('a' <= c && c <= 'f')
  209.                 return (c + 10 - 'a');
  210.         else if ('A' <= c && c <= 'F')
  211.                 return (c + 10 - 'A');
  212.         else
  213.                 return(0);
  214. }
  215.          if (i == T_EOL && !is_eof
  216.                                         && *linep == 0) {
  217.